package com.js.common.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.js.common.mapper.BaseMapper;
import com.js.common.response.TableResultResponse;
import com.js.common.service.BaseService;
import com.js.common.util.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

/**
 * @author： ygl
 * @date： 2018/10/25
 * @Description： 基础接口实现类
 */
public class BaseServiceImpl<T> implements BaseService<T> {

    @Autowired
    private BaseMapper<T> baseMapper;

    /**
     * 插入数据
     *
     * @param t 实体
     * @return 插入数据的个数
     */
    @Override
    public int insertSelective(T t) {
        return baseMapper.insertSelective(t);
    }

    /**
     * 批量插入数据
     *
     * @param list 实体集合
     * @return 插入数据的个数
     */
    @Override
    public int insertList(List<T> list) {
        return baseMapper.insertList(list);
    }

    /**
     * 物理删除实体
     *
     * @param t 实体
     * @return 删除数据的个数
     */
    @Override
    public int delete(T t) {
        return baseMapper.delete(t);
    }

    /**
     * 通过主键ID删除实体
     *
     * @param id 主键
     * @return
     */
    @Override
    public int deleteById(Object id) {
        return baseMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int deleteLogicById(Object id) {
        return 0;
    }

    /**
     * 根据主键更新实体全部字段，null值会被更新
     *
     * @param t 实体
     * @return
     */
    @Override
    public int updateById(T t) {
        return baseMapper.updateByPrimaryKey(t);
    }

    /**
     * 根据主键更新属性不为null的值
     *
     * @param t 实体
     * @return 更新数据的个数
     */
    @Override
    public int updateSelectiveById(T t) {
        return baseMapper.updateByPrimaryKeySelective(t);
    }

    //TODO 可以优化批量更新

    /**
     * 批量修改数据
     * 根据主键更新实体全部字段，null值会被更新
     * @param list 实体列表
     * @return 批量更新数据的个数
     */
    @Override
    public int updateList(List<T> list) {
        if (!CollectionUtils.isEmpty(list)) {
            int rows = 0;
            for (T t : list) {
                rows += updateById(t);
            }
            return rows;
        }
        return 0;
    }

    /**
     * 批量修改数据
     *根据主键更新属性不为null的值
     * @param list 实体列表
     * @return 批量更新数据的个数
     */
    @Override
    public int updateSelectiveList(List<T> list) {
        if (!CollectionUtils.isEmpty(list)) {
            int rows = 0;
            for (T t : list) {
                rows += updateSelectiveById(t);
            }
            return rows;
        }
        return 0;
    }

    @Override
    public List<T> selectAll() {
        return baseMapper.selectAll();
    }

    /**
     * 通过条件查询所有满足的实体
     * @param entity
     * @return
     */
    @Override
    public List<T> selectList(T entity) {
        return baseMapper.select(entity);
    }

    /**
     * 根据主键查询实体
     *
     * @param id 主键
     * @return 实体
     */
    @Override
    public T selectById(Object id) {
        return baseMapper.selectByPrimaryKey(id);
    }

    /**
     * 根据多个主键查询实体列表
     *
     * @param ids 主键,如 "1,2,3,4"
     * @return 实体列表
     */
    @Override
    public List<T> selectByIds(String ids) {
        return baseMapper.selectByIds(ids);
    }

    /**
     * 根据主键集合查询实体列表
     *
     * @param idArray 主键集合
     * @return 实体列表
     */
    @Override
    public List<T> selectByIdArray(String[] idArray) {
        String ids = StringUtils.arrayToDelimitedString(idArray, ",");
        return selectByIds(ids);
    }

    /**
     * 根据主键数组查询实体列表
     *
     * @param idList 主键数组
     * @return 实体列表
     */
    @Override
    public List<T> selectByIdList(List<String> idList) {
        String ids = StringUtils.collectionToDelimitedString(idList, ",");
        return selectByIds(ids);
    }

    /**
     * 根据自定义条件查询
     * @param example
     * @return
     */
    @Override
    public List<T> selectByExample(Object example) {
        return baseMapper.selectByExample(example);
    }

    /**
     * 分页查询
     * @param query
     * @return
     */
    @Override
    public TableResultResponse<T> selectByQuery(Query query) {
        Class<T> clazz = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        Example example = new Example(clazz);
        query2criteria(query, example);
        Page<Object> result = PageHelper.startPage(query.getPage(), query.getLimit());
        List<T> list = this.selectByExample(example);
        return new TableResultResponse<T>(result.getTotal(), list);
    }

    public void query2criteria(Query query, Example example) {
        if (query.entrySet().size() > 0) {
            Example.Criteria criteria = example.createCriteria();
            for (Map.Entry<String, Object> entry : query.entrySet()) {
                criteria.andLike(entry.getKey(), "%" + entry.getValue().toString() + "%");
            }
        }
    }
}
